package cn.xiaobai.core.repository.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.xiaobai.core.domain.factory.InConfFactory;
import cn.xiaobai.core.domain.factory.ToolFactoryBean;
import cn.xiaobai.core.repository.PluginDataFactory;
import com.gitee.starblues.integration.application.PluginApplication;
import com.gitee.starblues.integration.user.PluginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 默认插件数据工厂实现
 *
 * @Author yangdaji
 * @Date 2023/12/11
 * @PackageName cn.xiaobai.core.repository.impl
 * @ClassName DefaultPluginDataFactory
 */
@Repository
public class DefaultPluginDataFactory implements PluginDataFactory {

    private PluginUser pluginUser;

    private Map<String, InConfFactory> inConfFactoryMap = new ConcurrentHashMap<>();

    @Autowired
    public DefaultPluginDataFactory(PluginApplication pluginApplication) {
        this.pluginUser = pluginApplication.getPluginUser();
    }

    @Override
    public void init() {
        // 构建输入配置工厂
        this.buildFactory(InConfFactory.class, inConfFactoryMap);
    }

    @Override
    public boolean containPlugin(String type) {
        return inConfFactoryMap.containsKey(type);
    }

    @Override
    public boolean loadInConf(String type) {
        return this.buildFactory(InConfFactory.class, type, inConfFactoryMap);
    }

    @Override
    public InConfFactory getInConfFactory(String type) {
        return inConfFactoryMap.get(type);
    }

    @Override
    public Boolean removeInConfFactory(String type) {
        return inConfFactoryMap.remove(type) != null;
    }

    @Override
    public List<InConfFactory> getAllInConfFactorys() {
        return inConfFactoryMap.values().stream().toList();
    }

    /**
     * 构建所有工具工厂
     *
     * @param tClass
     * @param toolFactoryBeanMap
     * @param <T>
     * @return
     */
    private <T extends ToolFactoryBean<?>> void buildFactory(Class<T> tClass,
                                                             Map<String, T> toolFactoryBeanMap) {
        // 获取所有插件
        List<T> beans = pluginUser.getBeans(tClass);
        for (T bean : beans) {
            if (bean == null || StrUtil.isBlank(bean.getType())) {
                continue;
            }
            toolFactoryBeanMap.put(bean.getType(), bean);
        }
    }

    /**
     * 构建所有工具工厂, 根据类型
     *
     * @param tClass
     * @param type
     * @param toolFactoryBeanMap
     * @param <T>
     * @return
     */
    private <T extends ToolFactoryBean<?>> boolean buildFactory(Class<T> tClass, String type,
                                                                Map<String, T> toolFactoryBeanMap) {

        List<T> beans = pluginUser.getBeans(tClass);
        for (T bean : beans) {
            if (bean == null || StrUtil.isBlank(bean.getType())) {
                continue;
            }
            toolFactoryBeanMap.put(bean.getType(), bean);
        }
        List<T> typeList = beans.stream()
                .filter(b -> type.equals(b.getType()))
                .toList();
        if (ObjectUtil.isEmpty(typeList)) {
            return false;
        }
        typeList.forEach(b -> toolFactoryBeanMap.put(b.getType(), b));
        return true;
    }
}
